import { AfterViewInit, ChangeDetectionStrategy, Component, Injector, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ApiResToComponent } from '@basic';
import { SFSchema } from '@delon/form';
import { ArrayService } from '@delon/util';
import { BaseOfSystemForm } from '@routes/system/_base';
import { RoleForm, RoleVO } from '@types';
import { NzFormatEmitEvent, NzTreeComponent, NzTreeNode } from 'ng-zorro-antd/tree';
import { Observable } from 'rxjs';

import { SystemRoleService } from '../role.service';

@Component({
    selector: 'app-role-data-scope',
    templateUrl: './data-scope.component.html',
    styleUrls: ['./data-scope.component.less'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class SystemRoleDataScopeComponent extends BaseOfSystemForm<RoleForm, RoleVO> implements OnInit, AfterViewInit {
    dataScopeOptions = [
        { value: '1', label: '全部数据权限' },
        { value: '2', label: '自定数据权限' },
        { value: '3', label: '本部门数据权限' },
        { value: '4', label: '本部门及以下数据权限' },
        { value: '5', label: '仅本人数据权限' }
    ];

    validateForm: FormGroup = this.fb.group({
        roleName: [''],
        roleKey: [''],
        dataScope: ['0'],
        deptNodeAll: [false],
        deptCheckStrictly: [true],
        deptIds: []
    });

    @ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;

    defaultCheckStrictly: boolean = true;
    defaultCheckedKeys: any[] = [];
    nodes: NzTreeNode[] = [];
    /**
     * 是否展示树形结构
     */
    showDeptTree: boolean = false;

    constructor(
        protected override injector: Injector,
        private fb: FormBuilder,
        protected roleSrv: SystemRoleService,
        protected arrSrv: ArrayService
    ) {
        super(injector);
    }

    override ngOnInit() {
        this.roleSrv.getRole(this.item.roleId).subscribe(res => {
            const { roleName, roleKey, dataScope, deptCheckStrictly, status, remark } = this.validateForm.controls;
            roleName.setValue(res.data?.roleName ?? '');
            roleKey.setValue(res.data?.roleKey ?? '');
            dataScope.setValue(res.data?.dataScope ?? '0');
            deptCheckStrictly.setValue(res.data?.menuCheckStrictly ?? true);
        });
    }

    ngAfterViewInit(): void {
        // 数据权限范围变更
        this.validateForm.get('dataScope')?.valueChanges.subscribe(data => {
            if (data !== '2') {
                this.showDeptTree = false;
                this.defaultCheckedKeys = [];
                this.cdRef.detectChanges();
            } else {
                this.showDeptTree = true;
                this.roleSrv.deptTreeSelect(this.item.roleId).subscribe(res => {
                    this.arrSrv.visitTree(res.data?.depts ?? [], (item: any, parent) => {
                        item.title = item.label;
                        item.key = item.id;
                        item.isLeaf = !item.children;
                    });
                    this.nodes = res.data?.depts as any[];
                    this.defaultCheckedKeys = res.data?.checkedKeys ?? [];
                    this.cdRef.detectChanges();
                    this.validateForm.get('deptNodeAll')?.valueChanges.subscribe(data => {
                        let keys: any[] = [];
                        if (data) {
                            this.arrSrv.visitTree(this.nodes, (item, parent, level) => {
                                keys.push(item.key);
                            });
                        }
                        this.defaultCheckedKeys = keys;
                        this.cdRef.detectChanges();
                    });
                    this.validateForm.get('deptCheckStrictly')?.valueChanges.subscribe(data => {
                        this.defaultCheckStrictly = data ?? false;
                        this.cdRef.detectChanges();
                    });
                });
            }
        });
    }

    sendToServer(value: any): Observable<ApiResToComponent<RoleVO>> {
        return this.roleSrv.dataScope(value);
    }

    nzCheck(event: NzFormatEmitEvent) {
        if (event.eventName === 'check') {
            this.defaultCheckedKeys = this.arrSrv.getKeysByTreeNode(event.nodes!, { includeHalfChecked: false });
            this.cdRef.detectChanges();
        }
    }

    submitForm() {
        this.submit(this.validateForm.value);
    }

    schema: SFSchema = {
        properties: {}
    };

    override makeParams(value: any): RoleForm {
        let _temp = value;
        _temp.deptIds = this.defaultCheckedKeys;
        return { ..._temp, roleId: this.item.roleId };
    }
}
